package com.ruoyi.attendance.service.impl;

import com.ruoyi.attendance.domain.Attendance;
import com.ruoyi.attendance.domain.AttendanceStatistics;
import com.ruoyi.attendance.exception.BusinessException;
import com.ruoyi.attendance.exception.IsAdminBusinessException;
import com.ruoyi.attendance.mapper.AttendanceMapper;
import com.ruoyi.attendance.mapper.AttendanceStaticsMapper;
import com.ruoyi.attendance.service.IAttendanceService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;


@Service
@RequiredArgsConstructor
public class AttendanceServiceImpl implements IAttendanceService {

    private final AttendanceMapper attendanceMapper;

    private final AttendanceStaticsMapper attendanceStaticsMapper;

    /**
     * 分页查询考勤记录（带权限过滤）
     */
    @Override
    public List<Attendance> selectAttendanceList(Attendance attendance) {

        SysUser User = attendanceMapper.getRoleType(SecurityUtils.getUserId());

        //普通用户只能查询自己的考勤记录
        if (User.getRoleType() == 2) {
            attendance.setUserId(User.getUserId());
            return attendanceMapper.selectListByUserId(attendance);
        } else {
            //管理员用户查询所有考勤记录
            return attendanceMapper.selectList(attendance);
        }
    }

    /**
     * 上班打卡
     */
    @Override
    public Integer clockIn() {

        // 1. 检查用户是否是管理员
        SysUser User = getRoleType(SecurityUtils.getUserId());
        if (User.getRoleType() == 1) {
            throw new IsAdminBusinessException("管理员不用上班打卡");
        }

        // 2. 检查用户是否已打卡
        boolean hasClockedIn = hasClockedInToday(User.getUserId());

        if (hasClockedIn) {
            throw new BusinessException("您已打卡，无需重复操作");
        }


        // 2. 创建新的考勤记录
        Attendance attendance = new Attendance();
        attendance.setUserId(User.getUserId());
        attendance.setUserName(SecurityUtils.getUsername());
        attendance.setClockInTime(LocalDateTime.now());
        attendance.setCreateTime(new Date());
        //判断上班打卡时间是否超过9点,超过把状态设置为迟到
        if (attendance.getClockInTime().toLocalTime().isAfter(LocalTime.of(9, 0))) {
            attendance.setStatus(2);
        } else {
            attendance.setStatus(1);
        }
        //更新考勤记录
        attendanceMapper.insert(attendance);
        //更新考勤统计
        addAttendanceStatics(attendance.getStatus(), SecurityUtils.getUserId());
        return attendance.getStatus();
    }

    /**
     * 下班打卡
     */
    @Override
    public Integer clockOut() {
        //TODO 前端已经实现打过卡后禁用按钮,后端是否有必要再检查一次?

        // 1. 检查用户是否是管理员
        SysUser User = getRoleType(SecurityUtils.getUserId());
        if (User.getRoleType() == 1) {
            throw new IsAdminBusinessException("管理员不用下班打卡");
        }

        // 3. 检查用户是否已下班打卡
        boolean hasClockedOut = hasClockedOutToday(User.getUserId());
        if (hasClockedOut) {
            throw new BusinessException("您已下班打卡，无需重复操作");
        }


        // 2. 更新考勤记录状态为下班
        Attendance attendance = attendanceMapper.selectByClockInTime(User.getUserId(), LocalDateTime.now());
        attendance.setClockOutTime(LocalDateTime.now());
        //判断下班打卡时间是否早于18点,早于把状态设置为早退
        if (attendance.getClockOutTime().toLocalTime().isBefore(LocalTime.of(18, 0))) {
            attendance.setStatus(3);
        } else {
            attendance.setStatus(1);
        }
        //更新考勤记录

         attendanceMapper.updateById(attendance);
        //更新考勤统计
        addAttendanceStatics(attendance.getStatus(), SecurityUtils.getUserId());
        return attendance.getStatus();
    }

    /**
     * 获取用户角色类型
     */
    @Override
    public SysUser getRoleType(Long userId) {
        return attendanceMapper.getRoleType(userId);
    }


     /**
      * 根据用户ID查询考勤统计
      */
    @Override
    public AttendanceStatistics selectById() {
        AttendanceStatistics attendanceStatics = attendanceStaticsMapper.selectById(SecurityUtils.getUserId());

        /**
         * 如果用户不存在,则创建新的统计记录
         */
        if (attendanceStatics == null) {
            attendanceStatics = new AttendanceStatistics();
            attendanceStatics.setUserId(SecurityUtils.getUserId());
            attendanceStatics.setUserName(SecurityUtils.getUsername());
            attendanceStatics.setYearMonth(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")));
            attendanceStatics.setNormalCount(0);
            attendanceStatics.setLateCount(0);
            attendanceStatics.setEarlyLeaveCount(0);
            attendanceStatics.setAbsentCount(0);
            attendanceStatics.setCreateTime(new Date());
            attendanceStatics.setUpdateTime(new Date());
        }

        attendanceMapper.addAttendanceStatics(attendanceStatics);
        if (!attendanceStatics.getYearMonth().equals(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")))) {
            //清空统计记录
            attendanceStatics.setNormalCount(0);
            attendanceStatics.setLateCount(0);
            attendanceStatics.setEarlyLeaveCount(0);
            attendanceStatics.setAbsentCount(0);
            //更新统计年月
            attendanceStatics.setYearMonth(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")));
            //更新数据库
            attendanceStaticsMapper.update(attendanceStatics);
        }


        return attendanceStatics;
    }

    /**
     * 检查用户今天是否已下班打卡
     */
    private boolean hasClockedOutToday(Long userId) {
        // 计算当天00:00:00和23:59:59的时间范围
        LocalDateTime todayStart = LocalDate.now().atStartOfDay(); // 今天00:00:00
        LocalDateTime todayEnd = LocalDate.now().atTime(LocalTime.MAX); // 今天23:59:59.999...

        // 查询当天是否有下班打卡记录
        int count = attendanceMapper.countTodayClockOut(userId, todayStart, todayEnd);
        return count > 0; // 大于0表示已打卡
    }


    /**
     * 检查用户今天是否已上班打卡
     */
    public boolean hasClockedInToday(Long userId) {
        // 计算当天00:00:00和23:59:59的时间范围
        LocalDateTime todayStart = LocalDate.now().atStartOfDay(); // 今天00:00:00
        LocalDateTime todayEnd = LocalDate.now().atTime(LocalTime.MAX); // 今天23:59:59.999...

        // 查询当天是否有上班打卡记录
        int count = attendanceMapper.countTodayClockIn(userId, todayStart, todayEnd);
        return count > 0; // 大于0表示已打卡
    }


    /**
     * 添加考勤记录统计
     */
    public void addAttendanceStatics(Integer status, Long userId) {

        AttendanceStatistics attendanceStatics = attendanceStaticsMapper.selectById(userId);


        if (status == 1) {
            // 1. 正常上下班
            attendanceStatics.setNormalCount(attendanceStatics.getNormalCount() + 1);
        } else if (status == 2) {
            // 2. 迟到
            attendanceStatics.setLateCount(attendanceStatics.getLateCount() + 1);
        } else if (status == 3) {
            // 3. 早退
            attendanceStatics.setEarlyLeaveCount(attendanceStatics.getEarlyLeaveCount() + 1);
        } else if (status == 4) {
            // 4. 旷工
            attendanceStatics.setAbsentCount(attendanceStatics.getAbsentCount() + 1);
        }
        attendanceStaticsMapper.update(attendanceStatics);
    }
}